#include "NetworkStat.h"
#include "OS.h"


CCurUsedBindwidthCalc	*g_pRstpBindwidthCalc;


CCurUsedBindwidthCalc::CCurUsedBindwidthCalc()
{
	m_CalcWindow = 5; //s
	m_DownSumSize = 0;
	m_UpSumSize = 0;
}

CCurUsedBindwidthCalc::~CCurUsedBindwidthCalc()
{
//	printf("ycb_db Des CCurUsedBindwidthCalc\n");
	m_DownList.clear();
}

void CCurUsedBindwidthCalc::InputDownDataSize(UInt32 nDownDataSize)
{
	SInputDataSize sTmp;
	sTmp.m_DataSize = nDownDataSize;
	sTmp.m_UpdateTime = OS::Milliseconds();
	
	m_mtxDown.Lock();
	m_DownList.push_back(sTmp);
	m_DownSumSize += nDownDataSize;

	UInt64 uCurTime = OS::Milliseconds();
	list<SInputDataSize>::iterator it = m_DownList.begin();
	if(uCurTime - it->m_UpdateTime > (m_CalcWindow+10)*1000)
	{
		while(it!=m_DownList.end() && uCurTime - it->m_UpdateTime > m_CalcWindow*1000)
		{
			m_DownSumSize -= it->m_DataSize;
			m_DownList.pop_front();
			it = m_DownList.begin();
		}
	}
	
	m_mtxDown.Unlock();
}

void CCurUsedBindwidthCalc::InputUpDataSize(UInt32 nUpDataSize)
{
	SInputDataSize sTmp;
	sTmp.m_DataSize = nUpDataSize;
	sTmp.m_UpdateTime = OS::Milliseconds();
	
	m_mtxUp.Lock();
	m_UpList.push_back(sTmp);
	m_UpSumSize += nUpDataSize;

	UInt64 uCurTime = OS::Milliseconds();
	list<SInputDataSize>::iterator it = m_UpList.begin();
	if(uCurTime - it->m_UpdateTime > (m_CalcWindow+10)*1000)
	{
		while(it!=m_UpList.end() && uCurTime - it->m_UpdateTime > m_CalcWindow*1000)
		{
			m_UpSumSize -= it->m_DataSize;
			m_UpList.pop_front();
			it = m_UpList.begin();
		}
	}
	
	m_mtxUp.Unlock();
}

UInt32 CCurUsedBindwidthCalc::GetDownBindwidth()
{
	m_mtxDown.Lock();
	UInt64 uCurTime = OS::Milliseconds();
	list<SInputDataSize>::iterator it = m_DownList.begin();
	while(it!=m_DownList.end() && uCurTime - it->m_UpdateTime > m_CalcWindow*1000)
	{
		m_DownSumSize -= it->m_DataSize;
		m_DownList.pop_front();
		it = m_DownList.begin();
	}
	UInt32 nTmp = m_DownSumSize * 8 / m_CalcWindow;
	m_mtxDown.Unlock();
	
	return nTmp;
}

UInt32 CCurUsedBindwidthCalc::GetUpBindwidth()
{
	m_mtxUp.Lock();
	UInt64 uCurTime = OS::Milliseconds();
	list<SInputDataSize>::iterator it = m_UpList.begin();
	while(it!=m_UpList.end() && uCurTime - it->m_UpdateTime > m_CalcWindow*1000)
	{
		m_UpSumSize -= it->m_DataSize;
		m_UpList.pop_front();
		it = m_UpList.begin();
	}
	UInt32 nTmp = m_UpSumSize * 8 / m_CalcWindow;
	m_mtxUp.Unlock();
	
	return nTmp;
}

//////////////////////////////////////////
CLostPacketRateCalc::CLostPacketRateCalc()
{
	m_CalcWindow = 10000;
	m_SumRecved = 0;
	m_SumSended = 0;
}

CLostPacketRateCalc::~CLostPacketRateCalc()
{}

CLostPacketRateCalc & CLostPacketRateCalc::operator =( CLostPacketRateCalc & src )
{
	m_CalcWindow = src.m_CalcWindow;
	m_lstRecordPackets = src.m_lstRecordPackets;
	m_SumSended = src.m_SumSended;
	m_SumRecved = src.m_SumRecved;
	return *this;
}

void CLostPacketRateCalc::RecordPackets(UInt32 nSendedCount, UInt32 nRecvedCount)
{
	if(nSendedCount == 0)
		return;
	
	m_SumSended += nSendedCount;
	m_SumRecved += nRecvedCount;
	
	SSendedAndRecvedPackets sTmp;
	sTmp.m_SendedCount = nSendedCount;
	sTmp.m_RecvedCount = nRecvedCount;

	m_mtxRecordPackets.Lock();
	m_lstRecordPackets.push_back(sTmp);

	if(m_SumSended > m_CalcWindow + 5000)
	{
		while(m_SumSended > m_CalcWindow)
		{
			m_SumSended -= m_lstRecordPackets.front().m_SendedCount;
			m_SumRecved -= m_lstRecordPackets.front().m_RecvedCount;
			
			m_lstRecordPackets.pop_front();
		}
	}
	
	m_mtxRecordPackets.Unlock();
}

UInt32 CLostPacketRateCalc::GetLostRate()
{
	m_mtxRecordPackets.Lock();
	while(m_SumSended > m_CalcWindow)
	{
		m_SumSended -= m_lstRecordPackets.front().m_SendedCount;
		m_SumRecved -= m_lstRecordPackets.front().m_RecvedCount;

		m_lstRecordPackets.pop_front();
	}
	UInt32 nTmp = 0;
	if(m_SumSended >0)
		nTmp = (m_SumSended - m_SumRecved) * 10000 / m_SumSended;
	m_mtxRecordPackets.Unlock();

	return nTmp;
}



